// Author:
// Title:

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

/**
 * 计算二维点到轴对齐矩形的符号距离
 * @param p 点坐标
 * @param b 矩形的半尺寸（宽度和高度的一半）
 * @return 点到矩形的符号距离，负值表示点在矩形内部
 */
float sdBox(in vec2 p, in vec2 b) {
    vec2 d = abs(p)-b;
    return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
}

/**
 * 计算二维点到三角形的符号距离
 * @param p 点坐标
 * @param p0 三角形顶点0
 * @param p1 三角形顶点1
 * @param p2 三角形顶点2
 * @return 点到三角形的符号距离，负值表示点在三角形内部
 */
float sdTriangle( in vec2 p, in vec2 p0, in vec2 p1, in vec2 p2 ) {
    vec2 e0 = p1-p0, e1 = p2-p1, e2 = p0-p2;
    vec2 v0 = p -p0, v1 = p -p1, v2 = p -p2;
    vec2 pq0 = v0 - e0*clamp( dot(v0,e0)/dot(e0,e0), 0.0, 1.0 );
    vec2 pq1 = v1 - e1*clamp( dot(v1,e1)/dot(e1,e1), 0.0, 1.0 );
    vec2 pq2 = v2 - e2*clamp( dot(v2,e2)/dot(e2,e2), 0.0, 1.0 );
    float s = sign( e0.x*e2.y - e0.y*e2.x );
    vec2 d = min(min(vec2(dot(pq0,pq0), s*(v0.x*e0.y-v0.y*e0.x)),
                     vec2(dot(pq1,pq1), s*(v1.x*e1.y-v1.y*e1.x))),
                     vec2(dot(pq2,pq2), s*(v2.x*e2.y-v2.y*e2.x)));
    return -sqrt(d.x)*sign(d.y);
}

/**
 * 创建发光效果
 * @param load 距离场值，用于控制发光强度
 * @return 发光强度值，范围在0到1之间
 */
float createGlow(float load) {
   float a = step(0.,load)-step(1.,load);
   float b = smoothstep(1.2, load, 0.5);
   float c = min(a,b);
   return c;
}

// 颜色定义
const vec3 red = vec3(1.,0.,0.);
const vec3 orange = vec3(1., 150./255., 0.);
const vec3 yellow = vec3(1., 230./255., 0.);
const vec3 green = vec3(52./255.,211./255.,53./255.);
const vec3 blue = vec3(0.,180./255.,228./255.);

/**
 * 绘制场景内容
 * @param uv 归一化坐标
 * @return 该坐标处的颜色值
 */
vec3 drawScene(vec2 uv) {

    float t12s = fract(u_time/8.);
    vec3 col = vec3(0.2);
 
    // 构建电池外壳轮廓
    float boxBack = sdBox(uv, vec2(0.15, 0.32));
    float boxIn = sdBox(uv, vec2(0.135, 0.305));
    float top = sdBox(vec2(uv.x, uv.y - 0.325), vec2(0.08, 0.019));
    
    // 构建充电闪电形状
    vec2 p1 = vec2(-0.1, -0.15);
    vec2 p2 = vec2(0.01, -0.15);
    vec2 p3 = vec2(0.04, 0.125);
    float lightning1 = sdTriangle(vec2(uv.x,uv.y-0.115), p1, p2, p3);
    float lightning2 = sdTriangle(vec2(-uv.x,-uv.y-0.115), p1, p2, p3);
    float lightning = min(lightning1, lightning2);
    
    // 构建电池充电层级显示
    float bottomOff = 0.240;
    float heightLoad = 0.055;
    float load1 = sdBox(vec2(uv.x, uv.y + bottomOff), vec2(0.125, heightLoad));
    float load2 = sdBox(vec2(uv.x, uv.y + bottomOff-0.120*1.), vec2(0.125, heightLoad));
    float load3 = sdBox(vec2(uv.x, uv.y + bottomOff-0.120*2.), vec2(0.125, heightLoad));
    float load4 = sdBox(vec2(uv.x, uv.y + bottomOff-0.120*3.), vec2(0.125, heightLoad));
    float load5 = sdBox(vec2(uv.x, uv.y + bottomOff-0.120*4.), vec2(0.125, heightLoad));
    
    // 计算整体形状的最小距离
    float contour = max(boxBack, -boxIn);
    float res = min(contour, top);
    
    // 根据时间控制显示不同元素
    if (t12s < 0.83) {
        res = min(res, load2);
        res = min(res, load3);
        res = min(res, load4);
        res = min(res, load5);
    } else if (t12s < 1.) {
        res = min(lightning, res);
    }
    
    res = step(0., res);
    
    // 计算各层级的发光效果
    float finalLoad1 = createGlow(load1);
    float finalLoad2 = createGlow(load2);
    float step2Final = min(finalLoad1, finalLoad2);
    
    float finalLoad3 = createGlow(load3);
    float step3Final = min(step2Final, finalLoad3);
    
    float finalLoad4 = createGlow(load4);
    float step4Final = min(step3Final, finalLoad4);
    
    float finalLoad5 = createGlow(load5);
    float step5Final = min(step4Final, finalLoad5);
    
    // 根据时间显示不同颜色的充电效果
    col = mix(vec3(0,0,0), col, res);
    if (t12s < 0.17) {
        col = mix(blue, col, step5Final);
    } else if (t12s < 0.33) {
        col = mix(green, col, step4Final);
    } else if (t12s < 0.5) {
        col = mix(yellow, col, step3Final);
    } else if (t12s < 0.67) {
        col = mix(orange, col, step2Final);
    } else if (t12s < 0.83) {
        col = mix(red, col, finalLoad1);
    } else if (t12s < 1.) {
        col = mix(vec3(0,0,0), col, res);
    }
    return col;
}

/**
 * 主函数，处理片元着色
 */
void main() {
    // 将屏幕坐标转换为归一化坐标系
    vec2 uv = (gl_FragCoord.xy-0.5*u_resolution.xy)/min(u_resolution.x,u_resolution.y);
    vec3 col = drawScene(uv);
    gl_FragColor = vec4(col,1.0);
}